package com.ma5d.driver.common.login;

import com.ma5d.driver.common.constant.RedisConstant;
import com.ma5d.driver.common.exception.DriverException;
import com.ma5d.driver.common.result.ResultCodeEnum;
import com.ma5d.driver.common.util.AuthContextHolder;
import jakarta.annotation.Resource;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

@Component
@Aspect
public class MaLoginAspect {

    @Resource
    private RedisTemplate<String, String> redisTemplate;

    // 环绕通知：登陆判断
    // 切入点表达式：指定对那些规则的方法进行增强
    @Around("execution(* com.ma5d.driver.*.controller.*.*(..)) && @annotation(maLogin)")
    public Object login(ProceedingJoinPoint proceedingJoinPoint,
                        UserLogin maLogin) throws Throwable {
        // 1.获取 request 对象
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        // 2.从请求头获取 token
        String token = attributes.getRequest().getHeader("token");
        // 3.判断 token 是否为空，如果为空，返回登陆提示
        if(!StringUtils.hasText(token)) {
            throw new DriverException(ResultCodeEnum.LOGIN_AUTH);
        }
        // 4.token 非空， 查询redis
        String customerId = redisTemplate.opsForValue().get(RedisConstant.USER_LOGIN_KEY_PREFIX + token);
        // 5. 查询redis对应用户 id, 把用户 id 放到 ThreadLocal 里面
        if(StringUtils.hasText(customerId)) {
            AuthContextHolder.setUserId(Long.parseLong(customerId));
        }
        // 6.执行业务方法
        return proceedingJoinPoint.proceed();
    }

}
